package com.lxx.modules.sys.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.common.collect.ImmutableMap;
import com.lxx.annotation.PermissionName;
import com.lxx.common.BaseAction;
import com.lxx.dto.CaptchaDto;
import com.lxx.dto.SystemInfo;
import com.lxx.modules.sys.biz.ISysRoleBiz;
import com.lxx.modules.sys.biz.ISysUserBiz;
import com.lxx.modules.sys.entity.SysUser;
import com.lxx.utils.BeanUtils;
import com.lxx.utils.Config;
import com.lxx.utils.Constant;
import com.lxx.utils.DataTableResult;
import com.lxx.utils.ImageUtils;
import com.lxx.utils.Md5Utils;
import com.lxx.utils.NetworkUtil;
import com.lxx.utils.PageInfo;
import com.lxx.utils.Pagination;
import com.lxx.utils.ResponseUtils;
import com.lxx.utils.Result;
import com.lxx.utils.SystemInfoUtils;
import com.lxx.utils.ValidationUtils;
import com.lxx.utilsx.DateUtils;
import com.lxx.vo.PwdChangeVo;
import com.lxx.vo.WelcomeInfoVo;

//@RestController
@Controller
@RequestMapping("/user")
public class UserController extends BaseAction{
	private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
	
	@Autowired
	private ISysUserBiz sysUserBiz;
	@Autowired
	private ISysRoleBiz sysRoleBiz;
	
	@RequestMapping("/query")
	@ResponseBody
	@PermissionName("用户查询")
	public Result query(PageInfo pageInfo, HttpServletRequest request) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String beginStr = request.getParameter("begin");
		String endStr = request.getParameter("end");
		Map<String, Object> params = new HashMap<>();
		try {
			if (StringUtils.isNotBlank(beginStr)) {
				params.put("begin", format.parse(beginStr));
			}
			if (StringUtils.isNotBlank(endStr)) {
				params.put("end", format.parse(endStr));
			}
			params.put("keywords", request.getParameter("keywords"));
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		int pageIndex = pageInfo.getStart() / pageInfo.getLength() + 1;
		Pagination<SysUser> pagination = sysUserBiz.query(params, pageIndex, pageInfo.getLength());
		DataTableResult dataTableResult = new DataTableResult(pageInfo.getDraw(), 
				pagination.getTotalRow(), pagination.getTotalRow(), pagination.getDatas());
		return Result.success(dataTableResult);
	}
	
	@RequestMapping("/add")
	@ResponseBody
	@PermissionName("增加用户")
	public Result add(SysUser user) {
		LOGGER.debug("{}", user);
		user.setDelFlag(false);
		user.setCreateTime(new Date());
		user.setPassword(Constant.DEFAULT_PWD);
		ValidationUtils.validateForce(user);
		user.setPassword(Md5Utils.encode(user.getPassword()));
		sysUserBiz.save(user);
		
		// 用户角色关联
		sysUserBiz.updateUserRole(user.getId(), user.getRoleIds());
		
		return Result.SUCCESS;
	}
	
	@RequestMapping("/update")
	@ResponseBody
	@PermissionName("修改用户")
	public Result update(SysUser user) {
//		if (StringUtils.isNotBlank(user.getPassword())) {
//			user.setPassword(Md5Utils.encode(user.getPassword()));
//		}
		// 不支持改密码,因为无法知道原密码,显示不了原密码
		user.setPassword(null);
		sysUserBiz.update(user);
		
		// 用户角色关联
		sysUserBiz.updateUserRole(user.getId(), user.getRoleIds());
		return Result.SUCCESS;
	}
	
	@RequestMapping("/updateCurrentUserInfo")
	@ResponseBody
	@PermissionName("修改当前用户信息")
	public Result updateCurrentUserInfo(SysUser user) {
		user.setId(sessionUser().getId());
		sysUserBiz.update(user);
		
		// 修改完之后要更新session中的user信息
		BeanUtils.merge(user, sessionUser());
		
		return Result.SUCCESS;
	}
	
	@RequestMapping("/delete")
	@ResponseBody
	@PermissionName("删除用户")
	public Result delete(String ids) {
		sysUserBiz.delete(ids);
		return Result.SUCCESS;
	}
	
	@RequestMapping("/detail")
	@ResponseBody
	@PermissionName("用户详情")
	public Result detail(Integer id) {
		SysUser user = sysUserBiz.detail(id);
		return Result.success(user, "roleData", sysRoleBiz.getUserRoleData(id));
	}
	
	@RequestMapping("/currentUserInfo")
	@ResponseBody
	@PermissionName("获取当前用户信息")
	public Result currentUserInfo() {
		SysUser user = sessionUser();
		return Result.success(user);
	}
	
	@RequestMapping("/changeStatus")
	@ResponseBody
	@PermissionName("启用/停用")
	public Result changeStatus(Integer id, String status) {
		SysUser user = new SysUser();
		user.setStatus(status);
		user.setId(id);
		sysUserBiz.update(user);
		return Result.SUCCESS;
	}
	
	@RequestMapping(value="/changePwd", method=RequestMethod.POST)
	@ResponseBody
	@PermissionName("修改密码")
	public Result changePwd(PwdChangeVo pwdChangeVo) {
		SysUser user = sessionUser(session);
		ValidationUtils.validateForce(pwdChangeVo);
		if (!user.getPassword().equals(pwdChangeVo.getOldPwd())) {
			return Result.fail("旧密码输入错误");
		}
		user.setPassword(pwdChangeVo.getNewPwd());
		sysUserBiz.update(user);
		return Result.SUCCESS;
	}
	
	@RequestMapping("/toPage")
	public String toPage(String page, HttpSession session) {
		if (!"login".equals(page)) {
			if (!isLogged(session)) {
				// 如果未登陆，则跳转到登陆界面
				page = "redirect:/user/toPage.do?page=login";
			}
		}
		return page;
	}
	
	@RequestMapping("/login")
	@ResponseBody
	@PermissionName("用户登陆")
	public Result login(SysUser user, HttpServletRequest request, HttpSession session) {
		LOGGER.debug("{}", user);
		
		Object sessionCaptcha = session.getAttribute(Constant.CAPTCHA_NAME);
		if (sessionCaptcha != null && sessionCaptcha.toString().equalsIgnoreCase(user.getCaptcha())) {
			if (StringUtils.isNotBlank(user.getUsername()) && StringUtils.isNotBlank(user.getPassword())) {
				List<SysUser> users = sysUserBiz.query(ImmutableMap.of("username", user.getUsername(), "password", Md5Utils.encode(user.getPassword())), 
						1, 10).getDatas();
				if (users.size() == 1) {
					user = users.get(0);
					Config.lastLoginIp = user.getLastLoginIp();
					Config.lastLoginTime = user.getLastLoginTime();
					String ip = NetworkUtil.getIpAddress(request);
					user.setLastLoginIp(ip);
					user.setLastLoginTime(new Date());
					sysUserBiz.update(user);
					
					user.setPermissions(sysUserBiz.queryUserPermissions(user.getId()));
					
					saveUser2Session(request.getSession(), user);
					return Result.SUCCESS;
				}
			}
			return Result.fail("用户名或密码错误");
		}
		
		return Result.fail("验证码错误!");
	}
	
	@RequestMapping("/logout")
	@ResponseBody
	@PermissionName("用户登出")
	public Result logout(HttpSession session) {
//		LOGGER.debug("{}", user);
		invalidateSession(session);
		return Result.SUCCESS;
	}
	
	/**
	 * 查询当前用户的菜单
	 * @return
	 */
	@GetMapping("queryMenus")
	@ResponseBody
	@PermissionName("查询当前用户菜单")
	public Result queryMenus(HttpSession session) {
		return Result.success(sysUserBiz.queryMenus(sessionUser(session)));
	}
	
	/**
	 * 查询当前用户的菜单
	 * @return
	 */
	@GetMapping("captcha")
	@PermissionName("获取登陆验证码")
	public void captcha(HttpSession session, HttpServletResponse response) {
		CaptchaDto captchaDto = ImageUtils.generateCheckCode();
		byte[] data = captchaDto.getData();
		String code = captchaDto.getCode();
		session.setAttribute(Constant.CAPTCHA_NAME, code);
		
		response.setContentType("image/png");
		ResponseUtils.writeBytes(response, data);
	}
	
	/**
	 * 查询当前用户的菜单
	 * @return
	 */
	@GetMapping("welcomeInfo")
	@ResponseBody
	@PermissionName("获取欢迎页信息")
	public Result welcomeInfo(HttpSession session, HttpServletRequest request) {
		SystemInfo systemInfo = SystemInfoUtils.getSystemInfo();
		systemInfo.setSessionId(session.getId());
		systemInfo.setPort(String.valueOf(request.getLocalPort()));
		systemInfo.setSessionNum(String.valueOf(SystemInfoUtils.getSessionNum(request)));
		WelcomeInfoVo welcomeInfoVo = new WelcomeInfoVo();
		welcomeInfoVo.setSystemInfo(systemInfo);
//		SysUser user = sessionUser(session);
		welcomeInfoVo.setLastLoginIp(Config.lastLoginIp);
		welcomeInfoVo.setLastLoginTime(DateUtils.format(Config.lastLoginTime));
		return Result.success(welcomeInfoVo);
	}
	
	/**
	 * 用于重置密码,或用户忘记密码时,管理员可以重置并发送登陆信息至用户邮箱
	 * @return
	 */
	@PostMapping("sendLoginInfoMail")
	@ResponseBody
	@PermissionName("发送用户名和密码信息")
	public Result sendLoginInfoMail(Integer userId) {
		if (userId == null) {
			return Result.fail("参数错误");
		}
		sysUserBiz.resetPasswordAndSendLoginInfo(userId);
		return Result.SUCCESS;
	}
	
	/**
	 * 用于重置密码,或用户忘记密码时,管理员可以重置并发送登陆信息至用户邮箱
	 * @return
	 */
	@GetMapping("loginUserInfo")
	@ResponseBody
	@PermissionName("获取当前登陆用户信息")
	public Result loginUserInfo() {
		return Result.success(sessionUser().getUsername());
	}

}
